package com.ecoolex.discount.sales.admin.graphql;

import com.ecoolex.discount.sales.admin.core.AdminConstant;
import com.ecoolex.discount.sales.entity.*;
import com.ecoolex.discount.sales.enums.DiscountProductDiscountMode;
import com.ecoolex.discount.sales.enums.DiscountProductServiceType;
import com.ecoolex.discount.sales.enums.DiscountProductStatus;
import com.ecoolex.discount.sales.pojo.*;
import com.ecoolex.discount.sales.ws.DiscountProductService;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.service.storage.*;
import com.ecoolex.framework.web.api.graphql2.annotation.*;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;

import java.util.List;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

@GraphQL2Module(type = Type.Admin, description = "折扣产品")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_PROJECT_KEY,
        key = DiscountProductGraphql.AUTH,
        name = "折扣产品管理",
        remark = "折扣产品管理")
public class DiscountProductGraphql {
    public static final String AUTH = AdminConstant.AUTH_PROJECT_KEY + "-DISCOUNT-PRODUCT";
    public static final String AUTH_GET = AUTH + "-GET";
    public static final String AUTH_QUERY = AUTH + "-QUERY";
    public static final String AUTH_ADD = AUTH + "-ADD";
    public static final String AUTH_EDIT = AUTH + "-EDIT";
    public static final String AUTH_RELEASE = AUTH + "-RELEASE";
    public static final String AUTH_DEL = AUTH + "-DEL";

    
    public static final String AUTH_YOU_WORLD_GET = AUTH + "-YOU-WORLD-GET";
    public static final String AUTH_YOU_WORLD_QUERY = AUTH + "-YOU-WORLD-QUERY";
    public static final String AUTH_QUAN_MAO_QUERY = AUTH + "-QUAN-MAO-QUERY";

    @Reference
    private DiscountProductService discountProductService;

    @Autowired
    private StorageService storageService;
    
    @TypeField(type = DiscountProductWithBLOBs.class, field = "inventory", description = "有效库存")
    public Long inventory(@Source DiscountProductWithBLOBs source) {
    	return discountProductService.productInventory(source.getProductId());
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "brand", description = "品牌")
    public DiscountBrandWithBLOBs brand(@Source DiscountProductWithBLOBs source) {
        return discountProductService.getDiscountBrand(source.getBrandId());
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "image", description = "产品图片")
    public StorageInfo image(@Source DiscountProductWithBLOBs source) {
        return storageService.get(source.getImage());
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "canEdit", description = "是否能编辑")
    public boolean canEdit(@Source DiscountProductWithBLOBs source, AdminMemberAuthority user) {
        return user.auth(AUTH_EDIT);
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "canOnline", description = "是否能上线")
    public boolean canOnline(@Source DiscountProductWithBLOBs source, AdminMemberAuthority user) {
        return user.auth(AUTH_RELEASE) && DiscountProductStatus.canOnline(source);
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "canOffline", description = "是否能下线")
    public boolean canOffline(@Source DiscountProductWithBLOBs source, AdminMemberAuthority user) {
        return user.auth(AUTH_RELEASE) && DiscountProductStatus.canOffline(source);
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "canDel", description = "是否能删除")
    public boolean canDel(@Source DiscountProductWithBLOBs source, AdminMemberAuthority user) {
        return user.auth(AUTH_DEL) && DiscountProductStatus.canDel(source);
    }
    
    @TypeField(type = DiscountProductWithBLOBs.class, field = "attachList", description = "附加产品列表")
    public List<DiscountProductAttach> attachList(@Source DiscountProductWithBLOBs source){
    	return discountProductService.listByMainProductId(source.getProductId());
    }
    
    @TypeField(type = DiscountProductAttach.class, field = "discountProduct", description = "折扣产品")
    public DiscountProductWithBLOBs discountProduct(@Source DiscountProductAttach source){
    	return discountProductService.getProductById(source.getAttachProductId());
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "giftCard", description = "礼品卡信息")
    public DiscountProductGiftCard giftCard(@Source DiscountProductWithBLOBs source) {
        if (DiscountProductDiscountMode.GIFT_CARD.equal(source.getDiscountMode())) {
            return discountProductService.getGiftCardByProductId(source.getProductId());
        } else {
            return null;
        }
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "vouchers", description = "抵用券信息")
    public DiscountProductVouchers vouchers(@Source DiscountProductWithBLOBs source) {
        if (DiscountProductDiscountMode.VOUCHERS.equal(source.getDiscountMode())) {
            return discountProductService.getVouchersByProductId(source.getProductId());
        } else {
            return null;
        }
    }

    @TypeField(type = DiscountProductWithBLOBs.class, field = "recharge", description = "充值信息")
    public DiscountProductRecharge recharge(@Source DiscountProductWithBLOBs source) {
        if (DiscountProductDiscountMode.VOUCHERS.equal(source.getDiscountMode())) {
            return discountProductService.getRechargeByProductId(source.getProductId());
        } else {
            return null;
        }
    }

    @TypeField(type = YouWorldGiftCard.class, field = "correlationProductNumber", description = "关联产品数量")
    public long correlationProductNumber(@Source YouWorldGiftCard source) {
        return discountProductService.countProductService(DiscountProductServiceType.YOU_WORLD, String.valueOf(source.getCardId()));
    }

    @TypeField(type = QuanMaoCard.class, field = "correlationProductNumber", description = "关联产品数量")
    public long correlationProductNumber(@Source QuanMaoCard source) {
        return discountProductService.countProductService(DiscountProductServiceType.QUAN_MAO, String.valueOf(source.getCardNo()));
    }
    
    @QueryField(field = "youWorldDiscountProduct", description = "查询由我折扣产品")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_YOU_WORLD_GET, name = "查询由我折扣产品")
    public YouWorldGiftCard getYouWorldGiftCard(@NonNull Integer cardId, AdminMemberAuthority user) {
    	user.assertAuth(AUTH_YOU_WORLD_GET);
    	return discountProductService.getYouWorldGiftCard(cardId);
    }

    @QueryField(field = "youWorldDiscountProductList", description = "查询由我折扣产品列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_YOU_WORLD_QUERY, name = "查询由我折扣产品列表")
    public Pagination<YouWorldGiftCard> queryYouWorldGiftCard(String cardName,@NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_YOU_WORLD_QUERY);
        return discountProductService.queryYouWorldGiftCard(cardName,sorts, page);
    }

    @QueryField(field = "youWorldDiscountOrderList", description = "查询由我折扣订单列表")
    public Pagination<YouWorldGiftCardOrder> queryYouWorldGiftCard(@NonNull QueryYouWorldGiftCardOrderDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_YOU_WORLD_QUERY);
        return discountProductService.queryYouWorldGiftCardOrder(query, sorts, page);
    }

    @QueryField(field = "youWorldServiceProviderInfo", description = "由我服务提供者信息")
    public YouWorldServiceProviderInfoDTO getYouWorldServiceProviderInfo(AdminMemberAuthority user) {
        user.assertAuth(AUTH_YOU_WORLD_QUERY);
        return discountProductService.getYouWorldServiceProviderInfo();
    }

    @QueryField(field = "quanMaoDiscountProductList", description = "查询券猫折扣产品列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUAN_MAO_QUERY, name = "查询券猫折扣产品列表")
    public Pagination<QuanMaoCard> queryQuanMaoCard(@NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_QUAN_MAO_QUERY);
        return discountProductService.queryQuanMaoCard(sorts, page);
    }

    @QueryField(field = "quanMaoDiscountOrderList", description = "查询券猫折扣订单列表")
    public Pagination<QuanMaoCardOrder> queryQuanMaoCardOrder(@NonNull QueryQuanMaoCardOrderDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_YOU_WORLD_QUERY);
        return discountProductService.queryQuanMaoCardOrder(query, sorts, page);
    }

    @QueryField(field = "quanMaoServiceProviderInfo", description = "券猫服务提供者信息")
    public QuanMaoServiceProviderInfoDTO getQuanMaoServiceProviderInfo(AdminMemberAuthority user) {
        user.assertAuth(AUTH_YOU_WORLD_QUERY);
        return discountProductService.getQuanMaoServiceProviderInfo();
    }


    @QueryField(field = "discountProduct", description = "获取折扣产品详情")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取折扣产品详情")
    public DiscountProductWithBLOBs get(@NonNull Integer productId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_GET);
        return discountProductService.getProductById(productId);
    }

    @QueryField(field = "discountProductList", description = "查询折扣产品列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询折扣产品列表")
    public Pagination<DiscountProductWithBLOBs> queryProduct(@NonNull QueryDiscountProductDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_QUERY);
        return discountProductService.queryProduct(query, sorts, page);
    }

    @MutationField(field = "uploadDiscountProductImage", description = "上传折扣产品图片")
    public StorageInfo uploadDiscountProductImage(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource SOURCE_IMAGE = UploadSource.builder().withSource("DiscountProduct").withSourceValue("Image").build();
        UploadLimit LIMIT_IMAGE = UploadLimit.builder().withAllowMimeType(MimeType.IMAGE.alls()).withMaxSize(FileSize.MB.byteLength(5)).build();
        return storageService.upload(request, SOURCE_IMAGE, LIMIT_IMAGE);
    }

    @MutationField(field = "addDiscountProduct", description = "添加折扣产品")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加折扣产品")
    public DiscountProductWithBLOBs createProduct(@NonNull AddDiscountProductDTO add, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ADD);
        return discountProductService.createProduct(add, user.userName());
    }

    @MutationField(field = "editDiscountProduct", description = "编辑折扣产品")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑折扣产品信息")
    public boolean updateProduct(@NonNull Integer productId, @NonNull EditDiscountProductDTO edit, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        discountProductService.updateProduct(productId, edit, user.userName());
        return true;
    }

    @MutationField(field = "editDiscountProductGiftCard", description = "编辑折扣产品礼品卡")
    public boolean updateProductGiftCard(@NonNull Integer productId, @NonNull EditDiscountProductGiftCardDTO edit, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        discountProductService.updateProductGiftCard(productId, edit, user.userName());
        return true;
    }

    @MutationField(field = "editDiscountProductVouchers", description = "编辑折扣产品折扣券")
    public boolean updateProductVouchers(@NonNull Integer productId, @NonNull EditDiscountProductVouchersDTO edit, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        discountProductService.updateProductVouchers(productId, edit, user.userName());
        return true;
    }

    @MutationField(field = "editDiscountProductRecharge", description = "编辑折扣产品充值")
    public boolean updateProductVouchers(@NonNull Integer productId, @NonNull EditDiscountProductRechargeDTO edit, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        discountProductService.updateProductRecharge(productId, edit, user.userName());
        return true;
    }
    
    @MutationField(field = "editDiscountProductAttach", description = "编辑折扣附加产品")
    public boolean updateProductAttach(@NonNull Integer productId, @NonNull List<EditDiscountProductAttachDTO> attachList, AdminMemberAuthority user) {
    	user.assertAuth(AUTH_EDIT);
    	discountProductService.updateProductAttach(productId, attachList, user.userName());
    	return true;
    }

    @MutationField(field = "editDiscountProductMarketing", description = "编辑折扣产品营销")
    public boolean updateProductMarketing(@NonNull Integer productId, @NonNull EditDiscountProductOperationStrategyDTO edit, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        discountProductService.updateProductMarketing(productId, edit, user.userName());
        return true;
    }

    @MutationField(field = "onlineDiscountProduct", description = "上线折扣产品")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_RELEASE, name = "上线折扣产品")
    public boolean onlineProduct(@NonNull Integer productId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_RELEASE);
        discountProductService.onlineProduct(productId, user.userName());
        return true;
    }

    @MutationField(field = "offlineDiscountProduct", description = "下线折扣产品")
    public boolean offlineProduct(@NonNull Integer productId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_RELEASE);
        discountProductService.offlineProduct(productId, user.userName());
        return true;
    }

    @MutationField(field = "delDiscountProduct", description = "删除折扣产品")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除折扣产品")
    public boolean deleteProduct(@NonNull Integer productId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_DEL);
        discountProductService.deleteProduct(productId, user.userName());
        return true;
    }
}
